/*
 * Copyright (C) 2013 Daniel Wasilew <daniel.wasilew@codeminer.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.codeminer.parts.files;

import org.codeminer.parts.application.ApplicationContext;
import org.codeminer.parts.files.ProcessInfo.TrackKeys;

import java.io.*;
import java.nio.channels.FileChannel;

/**
 * @author Daniel Wasilew <daniel.wasilew@codeminer.org>
 */
class MoveTrackProcessor implements FileProcessor<ProcessInfo> {

    public MoveTrackProcessor() {
    }

    @Override
    public void process(ProcessInfo param, ApplicationContext applicationContext) throws ProcessException {
        File uploadedFile = param.getFile();

        final String artistPath = getEmpty(param, TrackKeys.ARTIST);
        final String albumPath = getEmpty(param, TrackKeys.ALBUM);
        final String trackNumber = getEmpty(param, TrackKeys.TRACK);
        final String title = getEmpty(param, TrackKeys.TITLE);

        StringBuilder pathBuilder = new StringBuilder();
        pathBuilder.append(artistPath.isEmpty() ? "Other" : artistPath.substring(0, 1));
        pathBuilder.append(File.separatorChar);
        pathBuilder.append(artistPath.isEmpty() ? "Other" : artistPath);
        pathBuilder.append(File.separatorChar);
        pathBuilder.append(albumPath.isEmpty() ? "Unknown" : albumPath);
        pathBuilder.append(File.separatorChar);
        pathBuilder.append(trackNumber.isEmpty() ? "00000" : trackNumber);
        pathBuilder.append(" - ");
        pathBuilder.append(title.isEmpty() ? "Unknown" : title);
        pathBuilder.append('.');
        pathBuilder.append(uploadedFile.getAbsolutePath().substring(uploadedFile.getAbsolutePath().lastIndexOf(".") + 1));

        File newTargetFile = new File(applicationContext.getLibraryFolder(), pathBuilder.toString());

        if (newTargetFile.exists()) {
            uploadedFile.delete();
            throw new ProcessException("file already uploaded");
        }

        File newTargetFolder = newTargetFile.getParentFile();
        newTargetFolder.mkdirs();
        try {
            moveFile(uploadedFile, newTargetFile);
        } catch (IOException ex) {
            throw new ProcessException("could not move file", ex);
        }
        param.put(TrackKeys.FILE, newTargetFile);

        StoreInDatabaseProcessor processor = new StoreInDatabaseProcessor();
        processor.process(param, applicationContext);
    }

    private String getEmpty(ProcessInfo param, TrackKeys key) {
        String trackNumber = param.getStringValue(key);
        if (trackNumber == null) {
            return "";
        } else {
            return trackNumber;
        }
    }

    private void moveFile(File uploadedFile, File newTargetFile) throws IOException {
        try (FileChannel out = new FileOutputStream(newTargetFile).getChannel(); FileChannel in = new FileInputStream(uploadedFile).getChannel()) {
            in.transferTo(0, in.size(), out);
        }
        uploadedFile.delete();
    }
}
